#!/usr/bin/env node

require('dotenv').config();
const net = require('net');
const chalk = require('chalk');
const fs = require('fs');

class RawFTPTest {
    constructor() {
        this.host = process.env.FTP_HOST;
        this.port = parseInt(process.env.FTP_PORT) || 21;
        this.user = process.env.FTP_USER;
        this.password = process.env.FTP_PASSWORD;
        this.controlSocket = null;
        this.dataSocket = null;
    }

    async testRawFTP() {
        console.log(chalk.blue('🧪 原生Socket FTP测试'));
        console.log(chalk.gray('=' .repeat(40)));
        console.log(chalk.cyan(`目标: ${this.host}:${this.port}`));
        console.log(chalk.cyan('模式: 主动模式 (PORT命令)'));
        console.log('');

        return new Promise((resolve, reject) => {
            this.controlSocket = new net.Socket();
            
            let step = 'connect';
            let authenticated = false;
            
            // 创建数据监听服务器
            const dataServer = net.createServer((socket) => {
                console.log(chalk.green('✓ 数据连接建立!'));
                this.dataSocket = socket;
                
                socket.on('data', (data) => {
                    console.log(chalk.cyan(`📥 收到数据: ${data.length} 字节`));
                });
                
                socket.on('end', () => {
                    console.log(chalk.yellow('📤 数据传输完成'));
                    dataServer.close();
                    resolve(true);
                });
                
                socket.on('error', (err) => {
                    console.log(chalk.red(`❌ 数据连接错误: ${err.message}`));
                    dataServer.close();
                    resolve(false);
                });
            });

            // 监听随机端口
            dataServer.listen(0, '0.0.0.0', () => {
                const dataPort = dataServer.address().port;
                console.log(chalk.gray(`数据端口: ${dataPort}`));
                
                // 建立控制连接
                this.controlSocket.connect(this.port, this.host);
            });

            this.controlSocket.on('connect', () => {
                console.log(chalk.green('✓ 控制连接建立'));
            });

            this.controlSocket.on('data', (data) => {
                const response = data.toString().trim();
                console.log(chalk.gray(`📨 ${response}`));

                if (response.startsWith('220') && step === 'connect') {
                    // 服务器欢迎消息
                    step = 'user';
                    this.controlSocket.write(`USER ${this.user}\r\n`);
                    
                } else if (response.startsWith('331') && step === 'user') {
                    // 需要密码
                    step = 'pass';
                    this.controlSocket.write(`PASS ${this.password}\r\n`);
                    
                } else if (response.startsWith('230') && step === 'pass') {
                    // 登录成功
                    console.log(chalk.green('✅ 认证成功!'));
                    authenticated = true;
                    step = 'type';
                    this.controlSocket.write('TYPE I\r\n');
                    
                } else if (response.startsWith('200') && step === 'type') {
                    // 设置二进制模式成功
                    step = 'port';
                    
                    // 获取本地IP和数据端口
                    const dataPort = dataServer.address().port;
                    const localIP = this.getLocalIP();
                    
                    const ip1 = parseInt(localIP.split('.')[0]);
                    const ip2 = parseInt(localIP.split('.')[1]);
                    const ip3 = parseInt(localIP.split('.')[2]);
                    const ip4 = parseInt(localIP.split('.')[3]);
                    const portHigh = Math.floor(dataPort / 256);
                    const portLow = dataPort % 256;
                    
                    const portCmd = `PORT ${ip1},${ip2},${ip3},${ip4},${portHigh},${portLow}`;
                    console.log(chalk.blue(`📤 发送: ${portCmd}`));
                    this.controlSocket.write(`${portCmd}\r\n`);
                    
                } else if (response.startsWith('200') && step === 'port') {
                    // PORT命令成功
                    console.log(chalk.green('✅ PORT命令成功!'));
                    step = 'stor';
                    
                    // 创建测试文件
                    fs.writeFileSync('./raw-test.txt', 'Raw FTP test content\nHello World!');
                    
                    // 发送STOR命令
                    console.log(chalk.blue('📤 发送: STOR /raw-test.txt'));
                    this.controlSocket.write('STOR /raw-test.txt\r\n');
                    
                } else if (response.startsWith('150') && step === 'stor') {
                    // 开始数据传输
                    console.log(chalk.green('✅ 开始数据传输!'));
                    
                    // 发送文件内容
                    const fileContent = fs.readFileSync('./raw-test.txt');
                    console.log(chalk.blue(`发送文件内容: ${fileContent.length} 字节`));
                    
                    // 等待数据连接建立后发送
                    setTimeout(() => {
                        if (this.dataSocket) {
                            this.dataSocket.write(fileContent);
                            this.dataSocket.end();
                        } else {
                            console.log(chalk.red('❌ 数据连接未建立'));
                            resolve(false);
                        }
                    }, 1000);
                    
                } else if (response.startsWith('226')) {
                    // 传输完成
                    console.log(chalk.green('🎉 文件传输成功!'));
                    this.controlSocket.end();
                    resolve(true);
                    
                } else if (response.startsWith('4') || response.startsWith('5')) {
                    // 错误响应
                    console.log(chalk.red(`❌ FTP错误: ${response}`));
                    this.controlSocket.end();
                    dataServer.close();
                    resolve(false);
                }
            });

            this.controlSocket.on('error', (err) => {
                console.log(chalk.red(`❌ 控制连接错误: ${err.message}`));
                dataServer.close();
                resolve(false);
            });

            this.controlSocket.on('close', () => {
                console.log(chalk.yellow('控制连接关闭'));
                dataServer.close();
            });

            // 超时处理
            setTimeout(() => {
                console.log(chalk.red('❌ 操作超时'));
                if (this.controlSocket) this.controlSocket.end();
                dataServer.close();
                resolve(false);
            }, 30000);
        });
    }

    getLocalIP() {
        const { networkInterfaces } = require('os');
        const nets = networkInterfaces();
        
        // 先尝试获取非内网IP
        for (const name of Object.keys(nets)) {
            for (const net of nets[name]) {
                if (net.family === 'IPv4' && !net.internal && !net.address.startsWith('192.168.') && !net.address.startsWith('10.')) {
                    return net.address;
                }
            }
        }
        
        // 如果没有，使用本地网络IP
        for (const name of Object.keys(nets)) {
            for (const net of nets[name]) {
                if (net.family === 'IPv4' && !net.internal) {
                    return net.address;
                }
            }
        }
        
        // 最后使用localhost
        return '127.0.0.1';
    }
}

if (require.main === module) {
    const test = new RawFTPTest();
    test.testRawFTP()
        .then(success => {
            console.log(success ? 
                chalk.green('\n🎉 原生FTP上传成功!') : 
                chalk.red('\n💔 原生FTP上传失败')
            );
            process.exit(success ? 0 : 1);
        })
        .catch(console.error);
}

module.exports = RawFTPTest;